<template>
    <el-dialog v-model="isOpen" title="全局Moran's I空间自相关分析结果" :border="true" align-center>
        <el-descriptions column="2" border>
            <el-descriptions-item label="Moran指数">
                {{ isNaN(Number(result.moranIndex)) ? result.moranIndex : Number(result.moranIndex).toFixed(4) }}
            </el-descriptions-item>
            <el-descriptions-item label="预期值">
                {{ isNaN(Number(result.expectedValue)) ? result.expectedValue : Number(result.expectedValue).toFixed(4) }}
            </el-descriptions-item>
            <el-descriptions-item label="方差">
                {{ isNaN(Number(result.variance)) ? result.variance : Number(result.variance).toFixed(4) }}
            </el-descriptions-item>
            <el-descriptions-item label="Z分数">
                {{ isNaN(Number(result.zscore)) ? result.zscore : Number(result.zscore).toFixed(4) }}
            </el-descriptions-item>
            <el-descriptions-item label="P值">
                {{ isNaN(Number(result.pvalue)) ? result.pvalue : Number(result.pvalue).toFixed(4) }}
            </el-descriptions-item>
            <el-descriptions-item label="显著性">{{ result.significant ? "显著" : "不显著" }}</el-descriptions-item>
            <el-descriptions-item label="空间模式" span="2">{{ result.pattern }}</el-descriptions-item>
            <el-descriptions-item label="计算时间" span="2">{{ result.computeTime }}ms</el-descriptions-item>
        </el-descriptions>

        <el-divider />

        <div ref="chartContainer" style="width: 100%;height: 400px" />

        <template #footer>
            <div class="dialog-footer">
                <el-button type="primary" @click="isOpen = false">
                    关闭
                </el-button>
            </div>
        </template>
    </el-dialog>
</template>

<script setup>
import { nextTick, ref, watch } from "vue"
import * as echarts             from "echarts"

let isOpen = defineModel()
let props  = defineProps([ "originalData", "result" ])

let chartContainer = ref(null)
let chartInstance  = ref(null)

watch(isOpen, (val) => {
    if(val){
        initChart()
    }
})

function initChart(){
    nextTick(() => {
        if(!chartContainer.value){
            return
        }
        if(!props.result){
            return
        }

        if(!chartInstance.value){
            chartInstance.value = echarts.init(chartContainer.value)
        }

        // 生成模拟的Moran散点图数据
        const generateMockData = () => {
            const points     = []
            const size       = 50 // 模拟50个空间单元
            const moranIndex = props.result.moranIndex

            if(moranIndex > 0){
                // 正相关：高-高、低-低聚集
                for(let i = 0; i < size; i++){
                    const x = (Math.random() - 0.5) * 2 // 标准化值(-1~1)
                    // 正相关：y与x同向
                    const y = x * (0.3 + Math.random() * 0.4) + (Math.random() - 0.5) * 0.2
                    points.push([ x, y ])
                }
            }
            else{
                // 负相关：高-低、低-高聚集
                for(let i = 0; i < size; i++){
                    const x = (Math.random() - 0.5) * 2
                    // 负相关：y与x反向
                    const y = -x * (0.3 + Math.random() * 0.4) + (Math.random() - 0.5) * 0.2
                    points.push([ x, y ])
                }
            }
            return points
        }

        const scatterData    = generateMockData()
        const quadrantLabels = [
            { name: "高-高 (HH)", position: [ "90%", "10%" ] }, // 第一象限
            { name: "低-高 (LH)", position: [ "10%", "10%" ] }, // 第二象限
            { name: "低-低 (LL)", position: [ "10%", "90%" ] }, // 第三象限
            { name: "高-低 (HL)", position: [ "90%", "90%" ] },  // 第四象限
        ]

        // 计算最佳拟合线
        const calculateRegressionLine = (data) => {
            const n     = data.length
            const sumX  = data.reduce((sum, [ x, y ]) => sum + x, 0)
            const sumY  = data.reduce((sum, [ x, y ]) => sum + y, 0)
            const sumXY = data.reduce((sum, [ x, y ]) => sum + x * y, 0)
            const sumX2 = data.reduce((sum, [ x, y ]) => sum + x * x, 0)

            const slope     = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX)
            const intercept = (sumY - slope * sumX) / n

            // 生成线的两个端点
            const minX = Math.min(...data.map(d => d[0]))
            const maxX = Math.max(...data.map(d => d[0]))
            return [
                [ minX, slope * minX + intercept ],
                [ maxX, slope * maxX + intercept ],
            ]
        }

        const regressionLine = calculateRegressionLine(scatterData)

        const option = {
            tooltip   : {
                trigger  : "item",
                formatter: (params) => {
                    const x = params.value[0].toFixed(2)
                    const y = params.value[1].toFixed(2)
                    return `标准化值: ${ x }<br/>空间滞后值: ${ y }`
                },
            },
            grid      : {
                left        : "10%",
                right       : "10%",
                bottom      : "10%",
                top         : "10%",
                containLabel: true,
            },
            xAxis     : {
                type     : "value",
                name     : "属性值（标准化）",
                splitLine: { lineStyle: { type: "dashed" } },
                axisLine : { lineStyle: { color: "#333" } },
                min      : -2,
                max      : 2,
            },
            yAxis     : {
                type     : "value",
                name     : "空间滞后值（标准化）",
                splitLine: { lineStyle: { type: "dashed" } },
                axisLine : { lineStyle: { color: "#333" } },
                min      : -2,
                max      : 2,
            },
            series    : [
                {
                    type      : "scatter",
                    data      : scatterData,
                    symbolSize: 8,
                    itemStyle : {
                        color: "#3498db",
                    },
                },
                // 原点参考线（x=0）
                {
                    type     : "line",
                    data     : [ [ -2, 0 ], [ 2, 0 ] ],
                    lineStyle: { color: "#999", type: "solid" },
                    symbol   : "none",
                    z        : 1,
                },
                // 原点参考线（y=0）
                {
                    type     : "line",
                    data     : [ [ 0, -2 ], [ 0, 2 ] ],
                    lineStyle: { color: "#999", type: "solid" },
                    symbol   : "none",
                    z        : 1,
                },
                // 最佳拟合线（Moran's I）
                {
                    type     : "line",
                    data     : regressionLine,
                    lineStyle: {
                        color: "#e74c3c",
                        width: 2,
                    },
                    symbol   : "none",
                    z        : 2,
                },
            ],
            annotation: {
                label: {
                    fontSize       : 12,
                    color          : "#333",
                    backgroundColor: "rgba(255, 255, 255, 0.7)",
                },
                data : [
                    ...quadrantLabels.map(label => ({
                        type    : "text",
                        position: label.position,
                        value   : label.name,
                    })),
                    {
                        type           : "text",
                        position       : [ "50%", "5%" ],
                        value          : `Moran's I = ${ props.result.moranIndex.toFixed(4) }`,
                        backgroundColor: "rgba(255, 255, 255, 0.8)",
                        padding        : [ 5, 10 ],
                        borderRadius   : 4,
                    },
                ],
            },
        }

        chartInstance.value.setOption(option)
    })
}
</script>

<style lang="scss" scoped>
</style>
